/*
 * Copyright (c) 2010, Johan T. Larsson All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the Mercenary Commander project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *      
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL JOHAN T. LARSSON BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package games.TBSGame;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Comparator;

import javax.microedition.khronos.opengles.GL10;

public class Tile {
	public Unit Unit = null;
	public boolean Passable = true;
	public int DefenseBonus = 0;
	public boolean Visible = false;
	
	transient private ResourceManager ResourceManager = games.TBSGame.ResourceManager.Singleton;
	transient int OverlayTexture = 0;

	public int OverlayResource = 0;

	public int Height = 0;
	
	FloatBuffer Coords;
	FloatBuffer TexCoords;
	
	private float TexAlignX = 0;
	private float TexAlignY = 0;
	float Alignment = 1.0f/8.0f;
	
	public static Tile CreateWater()
	{
		Tile tile = new Tile();
		tile.Passable = false;
		
		tile.TexAlignX = 2f/8f;
		
		return tile;
	}
	
	public static Tile CreateDesert()
	{
		Tile tile = new Tile();
		
		tile.Height = 2;
		
		return tile;
	}
	
	public static Tile CreateGrass()
	{
		Tile tile = new Tile();

		tile.TexAlignX = 1f/8f;
		
		tile.Height = 1;
		
		return tile;
	}
	
	public void OverlayCity()
	{
		DefenseBonus += 15;
		OverlayResource = R.drawable.city1;
	}
	
	public void OverlayForest()
	{
		DefenseBonus += 10;
		OverlayResource = R.drawable.forest;
	}
	
	public void InitCoords(int[] heights)
	{
//		float XC = 0.5f;
//		float XW = 1.0f;
//		float XE = 0.0f;
//		float YC = 0.5f;
//		float YN = 1.15f;
//		float YMN = 0.85f;
//		float YMS = 0.15f;
//		float YS = -0.15f;
		
		float LXW = 1.2f;
		float LXE = -0.2f;
		float LYN = 1.35f;
		float LYMN = 0.99f;
		float LYMS = 0.01f;
		float LYS = -0.35f;
		
		float XC = 0.5f;
		float XW = 1.0f;
		float XE = 0.0f;
		float YC = 0.5f;
		float YN = 1.15f;
		float YMN = 0.85f;
		float YMS = 0.15f;
		float YS = -0.15f;
		
		//An approximation - but good enough for now
//		float TXC = 0.5f;
//		float TXW = 0.16667f;
//		float TXE = 0.83333f;
//		
//		float TYC = 0.5f;
//		float TYN = 0.16667f;
//		float TYMN = 0.32f;
//		float TYMS = 0.68f;
//		float TYS = 0.83333f;
		
		float LTXW = 0.0f * Alignment + TexAlignX;
		float LTXE = 1.0f * Alignment + TexAlignX;
		float LTYN = 0.0f * Alignment + TexAlignY;
		float LTYMN = 0.22f * Alignment + TexAlignY;
		float LTYMS = 0.78f * Alignment + TexAlignY;
		float LTYS = 1.0f * Alignment + TexAlignY;
	    
		float TXC = 0.5f * Alignment + TexAlignX;
		float TXW = 0.141f * Alignment + TexAlignX;
		float TXE = 0.859f * Alignment + TexAlignX;
		
		float TYC = 0.5f * Alignment + TexAlignY;
		float TYN = 0.118f * Alignment + TexAlignY;
		float TYMN = 0.3f * Alignment + TexAlignY;
		float TYMS = 0.7f * Alignment + TexAlignY;
		float TYS = 0.892f * Alignment + TexAlignY;
		
		float hexVertices[] = {
				//Triangle NE
	    		XC, YC, 0,
	    		XC, YN, 0,
	    		XW, YMN, 0,
	    		//Triangle E
	    		XC, YC, 0,
	    		XW, YMN, 0,
	    		XW, YMS, 0,
	    		//Triangle SE
	    		XC, YC, 0,
	    		XW, YMS, 0,
	    		XC, YS, 0,
	    		//Triangle SW
	    		XC, YC, 0,
	    		XC, YS, 0,
	    		XE, YMS, 0,
	    		//Triangle W
	    		XC, YC, 0,
	    		XE, YMS, 0,
	    		XE, YMN, 0,
	    		//Triangle NW
	    		XC, YC, 0,
	    		XE, YMN, 0,
	    		XC, YN, 0};
		
	    float hexTexVertices[] = {
	    		TXC, TYC,
	    		TXC, TYN,
	    		TXE, TYMN,
	    		
	    		TXC, TYC,
	    		TXE, TYMN,
	    		TXE, TYMS,
	    		
	    		TXC, TYC,
	    		TXE, TYMS,
	    		TXC, TYS,
	    		
	    		TXC, TYC,
	    		TXC, TYS,
	    		TXW, TYMS,
	    		
	    		TXC, TYC,
	    		TXW, TYMS,
	    		TXW, TYMN,
	    		
	    		TXC, TYC,
	    		TXW, TYMN,
	    		TXC, TYN};
	    
	    if(Height > heights[0])
	    {
	    	hexVertices[4] = LYN;
	    	hexVertices[6] = LXW;
	    	hexVertices[7] = LYMN;
	    	
	    	hexTexVertices[3] = LTYN;
	    	hexTexVertices[4] = LTXE;
	    	hexTexVertices[5] = LTYMN;
	    }
	    
	    if(Height > heights[1])
	    {
	    	hexVertices[12] = LXW;
	    	hexVertices[13] = LYMN;
	    	hexVertices[15] = LXW;
	    	hexVertices[16] = LYMS;
	    	
	    	hexTexVertices[8] = LTXE;
	    	hexTexVertices[9] = LTYMN;
	    	hexTexVertices[10] = LTXE;
	    	hexTexVertices[11] = LTYMS;
	    }
	    
	    if(Height > heights[2])
	    {
	    	hexVertices[21] = LXW;
	    	hexVertices[22] = LYMS;
	    	hexVertices[25] = LYS;
	    	
	    	hexTexVertices[14] = LTXE;
	    	hexTexVertices[15] = LTYMS;
	    	hexTexVertices[17] = LTYS;
	    }
	    
	    if(Height > heights[3])
	    {
	    	hexVertices[31] = LYS;
	    	hexVertices[33] = LXE;
	    	hexVertices[34] = LYMS;
	    	
	    	hexTexVertices[21] = LTYS;
	    	hexTexVertices[22] = LTXW;
	    	hexTexVertices[23] = LTYMS;
	    }
	    
	    if(Height > heights[4])
	    {
	    	hexVertices[39] = LXE;
	    	hexVertices[40] = LYMS;
	    	hexVertices[42] = LXE;
	    	hexVertices[43] = LYMN;
	    	
	    	hexTexVertices[26] = LTXW;
	    	hexTexVertices[27] = LTYMS;
	    	hexTexVertices[28] = LTXW;
	    	hexTexVertices[29] = LTYMN;
	    }
	    
	    if(Height > heights[5])
	    {
	    	hexVertices[48] = LXE;
	    	hexVertices[49] = LYMN;
	    	hexVertices[52] = LYN;
	    	
	    	hexTexVertices[32] = LTXW;
	    	hexTexVertices[33] = LTYMN;
	    	hexTexVertices[35] = LTYN;
	    }

	    ByteBuffer hvbb = ByteBuffer.allocateDirect(hexVertices.length * 4);
	    hvbb.order(ByteOrder.nativeOrder());
	    Coords = hvbb.asFloatBuffer();
	    Coords.put(hexVertices);
	    Coords.position(0);
	    
	    ByteBuffer htbb = ByteBuffer.allocateDirect(hexTexVertices.length * 4);
	    htbb.order(ByteOrder.nativeOrder());
	    TexCoords = htbb.asFloatBuffer();
	    TexCoords.put(hexTexVertices);
	    TexCoords.position(0);
	}
	
	public void InitGraphics(GL10 gl)
	{
		if(OverlayResource != 0)
			OverlayTexture = ResourceManager.LoadTexture(gl, OverlayResource);
	}
	
	public void UnloadTextures(GL10 gl)
	{
		ResourceManager.DeleteTexture(gl, OverlayTexture);
		OverlayTexture = 0;
	}
	
	public void onSurfaceCreated(GL10 gl)
	{
		UnloadTextures(gl);
	}
	
	public void Render(GL10 gl)
	{		
		if(OverlayTexture == 0)
			InitGraphics(gl);
		
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, Coords);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, TexCoords);
		//gl.glBindTexture(GL10.GL_TEXTURE_2D, Texture);
        gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 18);
	}
	
	public void RenderOverlay(GL10 gl)
	{
        if(OverlayTexture != 0)
        {
        	gl.glBindTexture(GL10.GL_TEXTURE_2D, OverlayTexture);
        	gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 4);
        }	
	}
}
